Jak na zpravu WM_DRAWITEM - zmena barvy menu

Otázka od: Ing. Jiri SOKOL

25. 11. 2002 14:14

Ahoj,

chtel jsem si zmenit barvu MainMenu. V helphu a tak ruzne jsem se docetl, ze je
mozne tohoto
docilit, kdyz menu nastavim vlastnost OwnerDraw na true a odchytim si zpravu
WM_DRAWITEM.
OK, to jsem zvladl. Problem mam, ze lparametr teto zpravy je pointer na
pole(record) typu
DRAWITEMSTRUCT, ktere obsahuje "item-drawing information".
Jenze neumim ten parametr spravne pouzit. Delam toto:

procedure TForm1.WndProc(var msg:TMessage);
var
 Stru:TDrawItemStruct;
begin
 if (msg.message=WM_DRAWITEM)and(msg.wParam=0) then
   begin
     stru:=@msg.lparam;
     ShowMessage('Handle menu by mel byt: '+IntToStr(stru.hwndItem));
   end;
end;

Problem je v tom, ze se nedostavam ke spravnym datum. Nekde delam chybu, ale
netusim kde. Ten
pointer pouzivam nejspis spatne, ale jak je to spravne?

Poradite? Diky.

Jirka

Ing. Jiri Sokol, js-delphi@seznam.cz, +420251431187
D6ProfSP2,WinNT
amatersky programator

______________________________________________________________________
Reklama:
Poctenicko pro kazdy den: http://www.novinky.cz

Odpovedá: Ondrej Kelle

25. 11. 2002 15:41

> chtel jsem si zmenit barvu MainMenu. V helphu a tak ruzne
> jsem se docetl, ze je mozne tohoto
> docilit, kdyz menu nastavim vlastnost OwnerDraw na true a
> odchytim si zpravu WM_DRAWITEM.

V Delphi 6 nemusis tu spravu odchytavat, staci, ak si nastavis
TMainMenu.OwnerDraw na True (alebo priradis Images) a potom mozes pouzit
event OnDrawItem alebo OnAdvancedDrawItem. Musis ale ten event priradit
kazdej polozke zvlast.
Ak to chces priradit v runtime vsetkym polozkam v menu, da sa to napriklad
takto:

type
  TMenuItemProc = procedure (Item: TMenuItem) of object;

procedure TForm1.UpdateItem(Item: TMenuItem);
begin
  Item.OnDrawItem := MainMenu1DrawItem;
end;

procedure IterateMenuItems(Items: TMenuItem; IterateProc: TMenuItemProc);
var
  I: Integer;
begin
  for I := 0 to Items.Count - 1 do
    IterateMenuItems(Items[I], IterateProc);
  IterateProc(Items);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MainMenu1.OwnerDraw := True;
  IterateMenuItems(MainMenu1.Items, UpdateItem);
end;

procedure TForm1.MainMenu1DrawItem(Sender: TObject; ACanvas: TCanvas; ARect:
TRect; Selected: Boolean);
begin
  // a tu si uz kreslis sam
end;

HTH
TOndrej

Odpovedá: Jaroslav Buček

25. 11. 2002 17:02

----- Original Message -----
From: "Ing. Jiri SOKOL" <JS-delphi@seznam.cz>
OK, to jsem zvladl. Problem mam, ze lparametr teto zpravy je pointer na
pole(record) typu
DRAWITEMSTRUCT, ktere obsahuje "item-drawing information".
Jenze neumim ten parametr spravne pouzit. Delam toto:
-----------------------------

pCaption : PChar;
DI : PDrawItemStruct;

  DI := Ptr(msg.lparam);
  // DI.itemState = 1 kdyz je kurzor nad item - 257 je na Win2000
  // DI.itemState = 0 kdyz je kurzor mimo item
  // DI.itemAction = 1 kdyz polozka nebyla zobrazena a musi se vykreslit
  // DI.itemAction = 2 kdyz polozka byla zobrazena a nemusi se prekreslit

  pCaption := Ptr(DI.itemData); // vrati caption
  TextOut(DI.hDC, DI.rcItem.Left, DI.rcItem.Top, pCaption,
StrLen(pCaption));

Jsou to jen kousky z jednoho meho programu. Snad Ti to pomuze. Ty konstanty
jsem zjistoval nejak zbesile, takze ani nevim, jak se jmenuji spravne
konstanty.

Ahoj, Jarda

Odpovedá: Petr Vones

25. 11. 2002 16:55

From: "Jaroslav Buček" <bucek@eskon.cz>
> // DI.itemState = 1 kdyz je kurzor nad item - 257 je na Win2000
> // DI.itemState = 0 kdyz je kurzor mimo item
> // DI.itemAction = 1 kdyz polozka nebyla zobrazena a musi se vykreslit
> // DI.itemAction = 2 kdyz polozka byla zobrazena a nemusi se prekreslit

Tak takhle opravdu ne. Co se treba podivat do dokumentace a pouzit konstanty ?

ms-help://MS.PSDK.1033/shellcc/platform/commctls/comboboxes/comboboxreference/
comboboxstructures/drawitemstruct.htm

> Jsou to jen kousky z jednoho meho programu. Snad Ti to pomuze. Ty konstanty
> jsem zjistoval nejak zbesile, takze ani nevim, jak se jmenuji spravne
> konstanty.

Mozna by bylo dobre to delat zpusobem jakym to nabizi VCL, viz odpoved kterou
poslal Ondrej Kelle.

Petr Vones